package com.itheima.tanhua.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.itheima.tanhua.api.mongo.UserLocationApi;
import com.itheima.tanhuan.pojo.mongo.UserLocation;
import com.itheima.tanhuan.vo.mongo.UserLocationVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

@DubboService
public class UserLocationApiImpl implements UserLocationApi {
    @Autowired
    MongoTemplate mongoTemplate;


    @Override
    public void updateLocation(long uidId, double longitude, double latitude, String addrress) {
        GeoJsonPoint geoJsonPoint=new GeoJsonPoint(longitude,latitude);
        UserLocation userLocation=new UserLocation(null,uidId,geoJsonPoint,addrress,System.currentTimeMillis(),System.currentTimeMillis(),System.currentTimeMillis());
        mongoTemplate.save(userLocation,"user_location");
    }

    @Override
    public Boolean updateLocationByUid(Long uid, Double longitude, Double latitude, String address) {
        Query query=Query.query(Criteria.where("userId").is(uid));
        Update update=new Update();
        GeoJsonPoint geoJsonPoint=new GeoJsonPoint(longitude,latitude);
        update.set("location",geoJsonPoint);
        update.set("address",address);
        update.set("updated",System.currentTimeMillis());
        if (!isexit(uid)){
            update.set("created",System.currentTimeMillis());
            update.set("lastUpdated",System.currentTimeMillis());
        }else {
            update.set("lastUpdated",findUpdatedByUid(uid));
        }
        mongoTemplate.upsert(query,update,UserLocation.class);
        return true;
        }
//附近佳人
    @Override
    public List<Long> getNearUserVo(Circle circle, Long uid) {
        Query query=Query.query(Criteria.where("location").withinSphere(circle)).with(Sort.by(Sort.Order.desc("created")));
        List<UserLocation> userLocations = mongoTemplate.find(query, UserLocation.class);
        List<Long> userIds = CollUtil.getFieldValues(userLocations, "userId", Long.class);
        userIds.remove(uid);

        return userIds;
    }

    @Override
    public UserLocationVo findLocaltionByUid(Long uid) {
        UserLocation userLocation = mongoTemplate.findOne(Query.query(Criteria.where("userId").is(uid)), UserLocation.class);
        return UserLocationVo.getUserLocationVo(userLocation);
    }

    @Override
    public List<Long> getIds(Double longitude, Double latitude, String distance, Long uid) {
        GeoJsonPoint geoJsonPoint = new GeoJsonPoint(longitude, latitude);
        Distance distance1=new Distance(Convert.toDouble(distance)/1000);
        Circle circle=new Circle(geoJsonPoint,distance1);
        return getNearUserVo(circle, uid);
    }

    public Boolean isexit(Long uid){
            return mongoTemplate.exists(Query.query(Criteria.where("userId").is(uid)), UserLocation.class);
        }

    public Long findUpdatedByUid(Long uid){
        UserLocation userId = mongoTemplate.findOne(Query.query(Criteria.where("userId").is(uid)), UserLocation.class);
        return userId.getUpdated();
    }
}
